﻿using Avalonia.BiliBili.Libs;
using Avalonia.BiliBili.Libs.Models;
using Avalonia.BiliBili.Windows;
using Avalonia.Extensions.Controls;
using Bilibili.Common.Api;
using Bilibili.Common.Log;
using Bilibili.Model.Common;
using PCLUntils.Objects;
using System;
using System.Threading.Tasks;

namespace Avalonia.BiliBili.Units
{
    public sealed class AvMapper
    {
        private IApiClient ApiClient => StaticValue.ApiClient;
        public async Task<bool> HandelUrl(string url)
        {
            try
            {
                #region video
                if (url.Replace("aid", "av").Replace("/", "").Replace("=", "").RegexMatch(@"av(\d+)", out string video))
                {
                    NavigateToPlayer(video, PlayMode.Video);
                    return true;
                }
                if (url.RegexMatch(@"bilibili://video/(\d+)", out video))
                {
                    NavigateToPlayer(video, PlayMode.Video);
                    return true;
                }
                if (url.RegexMatch(@"avid=(\d+)", out video))
                {
                    NavigateToPlayer(video, PlayMode.Video);
                    return true;
                }
                if (url.RegexMatch(@"[Bb][Vv]([a-zA-Z0-9]{5,})", out video))
                {
                    NavigateToPlayer(video, PlayMode.Video);
                    return true;
                }
                #endregion
                #region ban
                if (url.Replace("movie", "ss").Replace("anime", "ss").Replace("season", "ss").Replace("/", "").RegexMatch(@"ss(\d+)", out string bangumi))
                {
                    NavigateToBang(bangumi);
                    return true;
                }
                if (url.RegexMatch(@"ep(\d+)", out bangumi))
                {
                    NavigateToBang(await BangumiEpidToSid(bangumi));
                    return true;
                }
                #endregion
                if (url.Replace("media", "md").Replace("review", "md").Replace("/", "").RegexMatch(@"md(\d+)", out string review))
                {
                    PopupToast.Show("请求打开点评" + review);
                    return true;
                }
                if (url.Replace("h5", "live").Replace("live.bilibili.com", "live").Replace("/", "").RegexMatch(@"live(\d+)", out string live))
                {
                    NavigateToPlayer(live, PlayMode.Live);
                    return true;
                }
                if (url.Replace("read/mobile/", "article").Replace("read/cv", "article").Replace("/", "").RegexMatch(@"article(\d+)", out string article))
                {
                    NavigateToWeb("https://www.bilibili.com/read/app/" + article, true);
                    return true;
                }
                if (url.Replace("bilibili://following/detail/", "album").Replace("h.bilibili.com/ywh/h5/", "album").Replace("h.bilibili.com", "album").Replace("t.bilibili.com", "album").Replace("/", "").RegexMatch(@"album(\d+)", out string album))
                {
                    Navigater.OpenWindow(typeof(DynamicInfoWindow), new DynamicCardsData(album));
                    return true;
                }
                if (url.Replace("space.bilibili.com", "space").Replace("author", "space").Replace("/", "").RegexMatch(@"space(\d+)", out string user))
                {
                    Navigater.OpenWindow(typeof(UserCenterWindow), user);
                    return true;
                }
                if (url.RegexMatch(@"tag/(.*?)/feed", out string topic))
                {
                    NavigateToTopic(new Tuple<string, string>(string.Empty, topic));
                    return true;
                }
                if ((url + "/").RegexMatch(@"tag/.*?/\?name=(.*?)/", out string topic1))
                {
                    var data = Uri.UnescapeDataString(topic1);
                    NavigateToTopic(new Tuple<string, string>(data, string.Empty));
                    return true;
                }
                if (url.Contains("/add_archive"))
                {
                    NavigateToWeb("https://member.bilibili.com/v2#/upload/video/frame", false);
                    return true;
                }
                if (url.Contains("favorite?tab=bangumi"))
                {
                    Navigater.OpenWindow(typeof(FollowSeasonWindow));
                    return true;
                }
                if (url.Contains("bilibili://pegasus/channel/v2/9222"))
                {
                    NavigateToWeb("https://www.bilibili.com/v/game/match", false);
                    return true;
                }
            }
            catch (Exception ex)
            {
                LogManager.Instance.LogError("HandelUrl", ex);
            }
            return false;
        }
        private async Task<string> BangumiEpidToSid(string url)
        {
            try
            {
                if (!url.Contains("http"))
                    url = "https://www.bilibili.com/bangumi/play/ep" + url;
                var re = await ApiClient.GetResultsUTF8Encode(url);
                return re.RegexMatch(@"ss(\d+)");
            }
            catch { return string.Empty; }
        }
        public string GetVideoId(string url)
        {
            try
            {
                string result = string.Empty;
                if (url.Replace("aid", "av").Replace("/", "").Replace("=", "").RegexMatch(@"av(\d+)", out result) && result.IsNotEmpty())
                    return result;
                if (url.RegexMatch(@"bilibili://video/(\d+)", out result) && result.IsNotEmpty())
                    return result;
                if (url.RegexMatch(@"avid=(\d+)", out result) && result.IsNotEmpty())
                    return result;
                if (url.RegexMatch(@"[Bb][Vv]([a-zA-Z0-9]{5,})", out result) && result.IsNotEmpty())
                    return result;
            }
            catch (Exception ex)
            {
                LogManager.Instance.LogError("GetVideoId", ex);
            }
            return url;
        }
        private void NavigateToBang(string url)
        {
            Navigater.OpenWindow(typeof(BanInfoWindow), url);
        }
        private void NavigateToWeb(string url, bool article)
        {
            Navigater.OpenWebView(url);
        }
        public void NavigateToPlayer(object data, PlayMode mode)
        {
            try
            {
                var videoWindow = Navigater.OpenWindow<VideoWindow>(data);
                videoWindow?.InitView(mode);
            }
            catch { }
        }
        private void NavigateToTopic(Tuple<string, string> tuple)
        {
            Navigater.OpenWindow(typeof(DynamicTopicWindow), tuple);
        }
    }
}